package com.nengchuan.kbms.dfs.service;

import com.nengchuan.config.exception.NcException;
import com.nengchuan.kbms.common.AutoWrapper;
import com.nengchuan.kbms.common.DfsTreeNode;
import com.nengchuan.kbms.common.PageServiceImpl;
import com.nengchuan.kbms.dfs.constant.BaseConstant;
import com.nengchuan.kbms.dfs.dao.DataFolderMapper;
import com.nengchuan.kbms.dfs.entity.dto.DataFolderDTO;
import com.nengchuan.kbms.dfs.entity.po.DataFolder;
import com.nengchuan.tree.util.NcTreeUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 文件夹 服务实现类
 * </p>
 *
 * @author luoping
 * @since 2020-03-24
 */
@Service
public class DataFolderServiceImpl extends PageServiceImpl<DataFolderMapper, DataFolder> implements DataFolderService {

    @Autowired
    private DataFolderMapper dataFolderMapper;

    @Autowired
    private DataFileService dataFileService;


    /**
     * 创建文件夹逻辑：
     * 1. 检查父文件夹id是否存在
     * 2. 文件夹名称移除尾部空格（允许左边空格
     * 3. 通过父文件夹id及文件夹名称检查文件夹是否已存在（已存在不允许创建
     * 4. 文件夹数据入库
     * // TODO 创建文件夹需要权限验证
     * @param dto
     * @return
     */
    @Override
    public Long saveFolder(DataFolderDTO dto) {
        // 方法内数据验证 （参数验证放在框架层处理
        Objects.requireNonNull(dto);
        Objects.requireNonNull(dto.getParentId());
        Objects.requireNonNull(dto.getFolderName());

        // 1
        assertFolderExisted(dto.getParentId());
        // 2
        dto.setFolderName(trimRight(dto.getFolderName()));
        // 3
        DataFolder dataFolder = getOne(new AutoWrapper<>(dto), false);
        if (dataFolder != null) {
            throw new NcException("文件名已存在，无法创建: " + dto.getFolderName());
        }
        // 4
        return insert(dto).getId();
    }

    /**
     * 更新文件夹逻辑：
     * 1. 检查父文件夹id是否存在，验证当前文件夹id是否存在
     * 2. 文件夹名称移除尾部空格（允许左边空格
     * 3. 验证同一文件夹内的文件夹名称是否存在（已存在不允许修改
     * 4. 数据入库
     * @param dto
     * @return
     */
    @Override
    public boolean updateFolder(DataFolderDTO dto) {
        Objects.requireNonNull(dto);
        Objects.requireNonNull(dto.getId());
        Objects.requireNonNull(dto.getParentId());
        Objects.requireNonNull(dto.getFolderName());

        // 1
        assertFolderExisted(dto.getParentId());
        assertFolderExisted(dto.getId());
        // 2
        dto.setFolderName(trimRight(dto.getFolderName()));
        // 3
        DataFolder dataFolder = getOne(new AutoWrapper<>(dto), false);
        if (dataFolder != null && dataFolder.getId() != dto.getId().longValue()) {
            throw new NcException("文件名已存在，无法修改: " + dto.getFolderName());
        }
        // 4
        return update(dto);
    }

    /**
     * 删除文件（夹）逻辑：
     * 文件夹删除后，子文件夹不进行操作（子文件找不到父文件夹自然不会挂载且不会显示
     * // TODO 文件夹恢复，文件恢复，文件删除权限
     * @param id
     * @return
     */
    @Override
    public boolean removeFolder(Serializable id) {
        boolean folderFlag = remove(id);
        boolean fileFlag = dataFileService.remove(id);
        return folderFlag || fileFlag;
    }

    /**
     * 简单结构
     */
    @Override
    public List<DfsTreeNode> simpleTree(Long rootId) {
        List<DfsTreeNode> nodeList = dataFolderMapper.simpleTree(rootId);
        nodeList.forEach(node -> setPart(node));
        return nodeList;
    }

    /**
     * 获取下级文件夹
     */
    @Override
    public List<DfsTreeNode> lazySimpleTree(Long folderId) {
        assertFolderExisted(folderId);
        List<DfsTreeNode> nodeList = dataFolderMapper.lazySimpleTree(folderId);
        nodeList.forEach(node -> setPart(node));
        return nodeList;
    }

    /**
     * 树形结构
     */
    @Override
    public List<DfsTreeNode> tree(Long rootId) {
        List<DfsTreeNode> nodeList = (List<DfsTreeNode>) NcTreeUtil.transform(simpleTree(rootId));
        if (CollectionUtils.isNotEmpty(nodeList)) {
            nodeList.forEach(node -> {
                node.setLeaf(CollectionUtils.isEmpty(node.getChild()));
                setPart(node);
            });
        }
        return nodeList;
    }

    /**
     * 验证文件夹存在
     */
    @Override
    public DataFolder assertFolderExisted(Long folderId) {
        DataFolder dataFolder = getById(folderId);
        if (dataFolder == null) {
            throw new NcException("文件夹不存在: " + folderId);
        }
        return dataFolder;
    }


    /**
     * 查询目标文件夹
     * @param parentId 父目录id
     * @param folderName  当前文件夹名称
     * @return
     */
    @Override
    public DataFolder queryFolder(long parentId, String folderName) {
        DataFolderDTO dto = new DataFolderDTO();
        dto.setParentId(parentId);
        dto.setFolderName(folderName);
        return getOne(new AutoWrapper<>(dto));
    }

    /**
     * 移除字符串右边空格
     */
    private String trimRight(String value) {
        if (value != null) {
            value = value.replaceAll("\\s+$", "");
        }
        return value;
    }

    private static void setPart(DfsTreeNode node) {
//        if (node != null && node.isLeaf()) {
//            node.setPart(BaseConstant.EQUIPMENT);
//        }
        if (node != null) {
            node.setPart(BaseConstant.EQUIPMENT);
        }
    }

}
